﻿@inject ISearchService searchService
@inject ICachedDataService cachedData
@using System.Globalization
@implements IDisposable

<div class="damselfly-dialogrow">
    <div class="damselfly-dialogctrl">
        <MudDateRangePicker @ref="_picker" Label="Date range" DateFormat="dd-MMM-yy" TitleDateFormat="dd-MMM-yyyy"
                            @bind-DateRange="DateRange" Variant="UIConstants.MudVariant"
                            Color="Color.Tertiary">
            <PickerActions>
                <MudButton Class="mr-auto align-self-start" OnClick="@(() => _picker.ClearAsync())">Clear</MudButton>
                <select class="mr-auto align-self-start" @onchange="ShortCutChanged">
                    <option>Quick Dates</option>
                    @foreach( var choice in DateRanges )
                    {
                        <option value="@choice.Key">@choice.Key</option>
                    }
                </select>
                <MudButton OnClick="@(() => _picker.CloseAsync(false))">Cancel</MudButton>
                <MudButton Color="Color.Primary" OnClick="@(() => _picker.CloseAsync())">Ok</MudButton>
            </PickerActions>
        </MudDateRangePicker>
    </div>
    <div class="damselfly-dialogctrl">
        <MultiSelectDropdown Label="Months" SourceData="monthChoices" @bind-SelectedItems="searchService.Months"
                             GetNameFunc="x => CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(x)"
                             GetShortNameFunc="x => CultureInfo.CurrentCulture.DateTimeFormat.GetAbbreviatedMonthName(x)"/>
    </div>
    <div class="damselfly-dialogctrl">
        <MudSelect T=" int? " Label="Rating" @bind-Value="searchService.MinRating" Clearable="true" Dense="true" Margin="Margin.Dense" Variant="UIConstants.MudVariant">
            @foreach( var choice in Enumerable.Range(1, 5).Reverse() )
            {
                <MudSelectItem T=" int? " Value="@choice">
                    <StarRating Rating="@choice" Editable="false"/>
                </MudSelectItem>
            }
        </MudSelect>
    </div>
    <div class="damselfly-dialogctrl">
        <MudSelect T=" FaceSearchType? " Label="People Filters" @bind-Value="searchService.FaceSearch" Clearable="true" Dense="true" Margin="Margin.Dense" Variant="UIConstants.MudVariant">
            @foreach( var choice in faceTypes )
            {
                <MudSelectItem T=" FaceSearchType? " Value="@choice">
                    @choice.ToString().Humanize()
                </MudSelectItem>
            }
        </MudSelect>
    </div>
    <div class="damselfly-dialogctrl">
        <MudSelect T=" OrientationType? " Label="Orientation" @bind-Value="searchService.Orientation" Clearable="true" Dense="true" Margin="Margin.Dense" Variant="UIConstants.MudVariant">
            @foreach( var choice in orientationTypes )
            {
                <MudSelectItem T=" OrientationType? " Value="@choice">
                    @choice.ToString().Humanize()
                </MudSelectItem>
            }
        </MudSelect>
    </div>
    <div class="damselfly-dialogctrl">
        <MudSelect T=" int? " Label="Camera Make/Model" @bind-Value="searchService.CameraId" Clearable="true" Dense="true" Margin="Margin.Dense" Variant="UIConstants.MudVariant">
            @foreach( var cam in cachedData.Cameras )
            {
                <MudSelectItem T=" int? " Value="@cam.CameraId">
                    @cam.Make @cam.Model
                </MudSelectItem>
            }
        </MudSelect>
    </div>
    <div class="damselfly-dialogctrl">
        <MudSelect T=" int? " Label="Lens Make/Model" @bind-Value="searchService.LensId" Clearable="true" Dense="true" Margin="Margin.Dense" Variant="UIConstants.MudVariant">
            @foreach( var lens in cachedData.Lenses )
            {
                <MudSelectItem T=" int? " Value="@lens.LensId">
                    @lens.Make @lens.Model
                </MudSelectItem>
            }
        </MudSelect>
    </div>
    <div class="damselfly-dialogctrl">
        <MudSelect T=" int? " Label="Max File Size" @bind-Value="searchService.MaxSizeKB" Clearable="true" Dense="true" Margin="Margin.Dense" Variant="UIConstants.MudVariant">
            @foreach( var choice in fileSizeChoices )
            {
                <MudSelectItem T=" int? " Value="@choice.Value">
                    @choice.Key
                </MudSelectItem>
            }
        </MudSelect>
    </div>
    <div class="damselfly-dialogctrl">
        <MudSelect T=" int? " Label="Min File Size" @bind-Value="searchService.MinSizeKB" Clearable="true" Dense="true" Margin="Margin.Dense" Variant="UIConstants.MudVariant">
            @foreach( var choice in fileSizeChoices )
            {
                <MudSelectItem T=" int? " Value="@choice.Value">
                    @choice.Key
                </MudSelectItem>
            }
        </MudSelect>
    </div>
    <div class="damselfly-dialogctrl">
        <MudCheckBox @bind-Value="@searchService.TagsOnly" Label="Exclude filenames/folders"/>
    </div>
    <div class="damselfly-dialogctrl">
        <MudCheckBox @bind-Value="@searchService.IncludeAITags" Label="Include AI tags"/>
    </div>
    <div class="damselfly-dialogctrl">
        <MudCheckBox @bind-Value="@searchService.UntaggedImages" Label="Images without keywords"/>
    </div>
</div>

@code {
    MudDateRangePicker _picker;
    List<KeyValuePair<string, DateRange>> DateRanges = new();
    DateRange filterRange = new();

    private Task FilterChanged()
    {
        return Task.CompletedTask;
    }

    DateRange DateRange
    {
        get => filterRange;
        set
        {
            filterRange = value;
            DateRangeChanged(value);
        }
    }


    private void ShortCutChanged(ChangeEventArgs e)
    {
        var shortCut = e.Value as string;

        if( shortCut != null )
        {
            var range = DateRanges.Where(x => x.Key == shortCut).Select(x => x.Value).FirstOrDefault();

            if( range != null )
                DateRange = range;
        }
    }

    private void DateRangeChanged(DateRange value)
    {
        if( value != null )
            searchService.SetDateRange(value.Start, value.End);
        else
            searchService.SetDateRange(null, null);
    }

    protected override void OnInitialized()
    {
        CreateShortcuts();
        filterRange = new DateRange(searchService.MinDate, searchService.MaxDate);

        // TODO: Can we do better than do this every time the advanced Search panel opens?
        cachedData.InitialiseData();

        base.OnInitialized();
    }

    private List<FaceSearchType> faceTypes = EnumerableExtensions.GetEnumList<FaceSearchType>();
    private List<OrientationType> orientationTypes = EnumerableExtensions.GetEnumList<OrientationType>();

    private List<KeyValuePair<string, int>> fileSizeChoices = new()
    {
        new KeyValuePair<string, int>("1KB", 1),
        new KeyValuePair<string, int>("50KB", 50),
        new KeyValuePair<string, int>("500KB", 500),
        new KeyValuePair<string, int>("1MB", 1024),
        new KeyValuePair<string, int>("5MB", 5 * 1024),
        new KeyValuePair<string, int>("10MB", 10 * 1024),
        new KeyValuePair<string, int>("50MB", 50 * 1024)
    };

    private Task<IEnumerable<int>> monthChoices => Task.FromResult<IEnumerable<int>>(Enumerable.Range(1, 12).ToList());

    protected override void OnAfterRender(bool firstRender)
    {
        base.OnAfterRender(firstRender);

        if( firstRender )
        {
            searchService.OnSearchQueryChanged += OnSearchChanged;
        }
    }

    public void Dispose()
    {
        searchService.OnSearchQueryChanged -= OnSearchChanged;
    }

    private void OnSearchChanged()
    {
        filterRange = new DateRange(searchService.MinDate, searchService.MaxDate);

        StateHasChanged();
    }

    private void AddRangeShortcut(string name, DateRange range)
    {
        DateRanges.Add(new KeyValuePair<string, DateRange>(name, range));
    }

    private void CreateShortcuts()
    {
        // TODO: Add more here
        var Jan1ThisYear = new DateTime(DateTime.UtcNow.Year, 1, 1);

        AddRangeShortcut("This year", new DateRange { Start = Jan1ThisYear, End = DateTime.UtcNow });
        AddRangeShortcut("Last year", new DateRange { Start = Jan1ThisYear.AddYears(-1), End = Jan1ThisYear.AddSeconds(-1) });
        AddRangeShortcut($"{Jan1ThisYear.AddYears(-2).Year}", new DateRange { Start = Jan1ThisYear.AddYears(-2), End = Jan1ThisYear.AddYears(-1).AddSeconds(-1) });
        AddRangeShortcut($"{Jan1ThisYear.AddYears(-3).Year}", new DateRange { Start = Jan1ThisYear.AddYears(-3), End = Jan1ThisYear.AddYears(-2).AddSeconds(-1) });
        AddRangeShortcut($"{Jan1ThisYear.AddYears(-4).Year}", new DateRange { Start = Jan1ThisYear.AddYears(-4), End = Jan1ThisYear.AddYears(-3).AddSeconds(-1) });
        AddRangeShortcut($"{Jan1ThisYear.AddYears(-5).Year}", new DateRange { Start = Jan1ThisYear.AddYears(-5), End = Jan1ThisYear.AddYears(-4).AddSeconds(-1) });
        AddRangeShortcut($"{Jan1ThisYear.AddYears(-10).Year}", new DateRange { Start = Jan1ThisYear.AddYears(-10), End = Jan1ThisYear.AddYears(-9).AddSeconds(-1) });
    }

}